package com.dongzili.easyes.common.es;

import cn.hutool.extra.spring.SpringUtil;
import com.dongzili.easyes.common.mybatisplus.PropertyQueryWrapper;
import com.dongzili.easyes.common.utils.QueryWrapperSqlHelper;
import com.dongzili.easyes.common.utils.ReflectUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.dromara.easyes.core.kernel.BaseEsMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class EsUtils {

    private final static Logger log = LoggerFactory.getLogger(EsUtils.class);
    private final static Map<Class<?>, BaseEsMapper<?>> MAPPER_MAP = new ConcurrentHashMap<>();

    @SuppressWarnings("unchecked")
    public static <T> BaseEsMapper<T> getMapper(final Class<T> t) {
        if (MAPPER_MAP.containsKey(t)){
            return (BaseEsMapper<T>) MAPPER_MAP.get(t);
        }
        BaseEsMapper<?> mapper = SpringUtil.getBean(getBeanName(t) + "AutoEsMapper");
        MAPPER_MAP.put(t, mapper);
        return (BaseEsMapper<T>)mapper;
    }

    /**
     * 获取bean名称
     * @param t
     * @return
     */
    private static <T> String getBeanName(final Class<T> t) {
        return t.getSimpleName().substring(0, 1).toLowerCase() + t.getSimpleName().substring(1);
    }


    private static final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 将JSON字符串解析为字段-值映射列表
     * @param json 包含columns和rows结构的JSON字符串
     * @return 解析后的List<Map<String, Object>>，每个Map对应一行数据
     * @throws Exception 解析过程中发生的异常
     */
    @SuppressWarnings("unchecked")
    private static List<Map<String, Object>> parseJsonToMapList(String json){
        // 验证输入
        if (json == null || json.trim().isEmpty()) {
            throw new IllegalArgumentException("JSON字符串不能为空");
        }
        try{
            // 解析顶层JSON结构
            Map<String, Object> rootMap = objectMapper.readValue(json, new TypeReference<Map<String, Object>>() {});

            // 提取columns和rows
            List<Map<String, String>> columns = (List<Map<String, String>>) rootMap.get("columns");
            List<List<Object>> rows = (List<List<Object>>) rootMap.get("rows");

            // 验证必要字段
            if (columns == null || rows == null) {
                throw new IllegalArgumentException("JSON格式不正确，缺少columns或rows字段");
            }
            if (columns.isEmpty()) {
                throw new IllegalArgumentException("columns字段不能为空");
            }

            // 转换为字段-值映射列表
            List<Map<String, Object>> resultList = new ArrayList<>(rows.size());
            for (List<Object> row : rows) {
                // 验证行数据长度与列定义是否匹配
                if (row.size() != columns.size()) {
                    throw new IllegalArgumentException("行数据长度与columns定义不匹配，行数据长度：" + row.size() +
                            "，columns长度：" + columns.size());
                }

                Map<String, Object> rowMap = new HashMap<>(columns.size());
                for (int i = 0; i < columns.size(); i++) {
                    String fieldName = columns.get(i).get("name");
                    if (fieldName == null || fieldName.trim().isEmpty()) {
                        throw new IllegalArgumentException("columns中存在空的name字段");
                    }
                    rowMap.put(fieldName, row.get(i));
                }
                resultList.add(rowMap);
            }

            return resultList;
        }catch (Exception e){
            throw new RuntimeException("解析JSON字符串失败", e);
        }

    }


    public static <T> List<Map<String, Object>> selectListMap(PropertyQueryWrapper<T> wrapper, Class<T> clazz) {
        // 通过MyBatis-Plus的SQL辅助类获取查询SQL语句
        String sql = QueryWrapperSqlHelper.getSql(wrapper, clazz);//MpSqlHelper.getSelectListSQL(wrapper, clazz);
        // 执行SQL查询并获取结果字符串
        String resStr = getMapper(clazz).executeSQL(sql);
        // 将JSON格式结果字符串解析为Map列表
        return parseJsonToMapList(resStr);
    }

    public static <T,K> List<Map<String, Object>> selectListMap(BaseEsMapper<K> mapper, PropertyQueryWrapper<T> wrapper, Class<T> clazz) {
        // 通过MyBatis-Plus的SQL辅助类获取查询SQL语句
        String sql = QueryWrapperSqlHelper.getSql(wrapper, clazz);//MpSqlHelper.getSelectListSQL(wrapper, clazz);
        log.info("es执行sql： {}", sql);
        // 执行SQL查询并获取结果字符串
        String resStr = mapper.executeSQL(sql);
        // 将JSON格式结果字符串解析为Map列表
        return parseJsonToMapList(resStr);
    }

    public static <T> List<T> selectList(PropertyQueryWrapper<T> wrapper, Class<T> entityClazz) {
        List<Map<String, Object>> maps = selectListMap(wrapper, entityClazz);
        return ReflectUtils.convertWithJackson(maps, entityClazz);
    }

    public static <T,V> List<V> selectList(PropertyQueryWrapper<T> wrapper, Class<T> sourceClazz, Class<V> targetClass) {
        List<Map<String, Object>> maps = selectListMap(wrapper, sourceClazz);
        return ReflectUtils.convertWithJackson(maps, targetClass);
    }
    public static <T,V,K> List<V> selectList(BaseEsMapper<K> mapper, Class<T> sourceClazz, PropertyQueryWrapper<T> wrapper, Class<V> targetClass) {
        List<Map<String, Object>> maps = selectListMap(mapper, wrapper, sourceClazz);
        return ReflectUtils.convertWithJackson(maps, targetClass);
    }

}
